<template>
  <div class="dashboard-page">
    <header class="topbar">
      <div class="brand">
        <div class="logo">S</div>
        <span class="system-name">SaaS 学生管理系统</span>
      </div>
      <div class="topbar-actions">
        <el-tooltip content="折叠菜单" placement="bottom">
          <el-button class="collapse-btn" link @click="toggleAside">
            <el-icon>
              <Fold v-if="!isCollapsed" />
              <Expand v-else />
            </el-icon>
          </el-button>
        </el-tooltip>
        <el-dropdown @command="handleCommand">
          <span class="avatar-trigger">
            <el-avatar :size="32" src="https://unavatar.io/github/vercel"></el-avatar>
            <el-icon class="dropdown-icon">
              <ArrowDown />
            </el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="profile">个人中心</el-dropdown-item>
              <el-dropdown-item divided command="logout">退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </header>

    <aside class="sidebar" :style="{ width: asideWidth + 'px' }">
      <el-menu class="menu" :default-active="activeMenu" :collapse="isCollapsed" @select="handleMenuSelect">
        <el-menu-item index="dashboard">
          <el-icon>
            <Monitor />
          </el-icon>
          <span>仪表盘</span>
        </el-menu-item>
        <el-menu-item index="users">
          <el-icon>
            <UserFilled />
          </el-icon>
          <span>用户管理</span>
        </el-menu-item>
        <el-menu-item index="orders">
          <el-icon>
            <ShoppingCart />
          </el-icon>
          <span>订单管理</span>
        </el-menu-item>
        <el-menu-item index="settings">
          <el-icon>
            <Setting />
          </el-icon>
          <span>系统设置</span>
        </el-menu-item>
      </el-menu>
    </aside>

    <main class="main" :style="{ marginLeft: asideWidth + 'px' }">
      <div class="content">
        <el-row :gutter="16" class="stats-row">
          <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-for="item in stats" :key="item.title">
            <el-card class="stat-card" shadow="hover">
              <div class="stat-card-inner">
                <div class="stat-icon" :style="{ backgroundColor: item.bg }">
                  <el-icon :size="22">
                    <component :is="item.icon" />
                  </el-icon>
                </div>
                <div class="stat-meta">
                  <div class="stat-title">{{ item.title }}</div>
                  <div class="stat-value">{{ item.value }}</div>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>

        <el-row :gutter="16" class="charts-row">
          <el-col :xs="24" :lg="16">
            <el-card class="chart-card" shadow="never">
              <template #header>
                <div class="card-header">
                  <span>最近 7 天访问量趋势</span>
                </div>
              </template>
              <div ref="lineChartRef" class="echart"></div>
            </el-card>
          </el-col>
          <el-col :xs="24" :lg="8">
            <el-card class="chart-card" shadow="never">
              <template #header>
                <div class="card-header">
                  <span>付费用户占比</span>
                </div>
              </template>
              <div ref="pieChartRef" class="echart"></div>
            </el-card>
          </el-col>
        </el-row>

        <el-card class="table-card" shadow="never">
          <template #header>
            <div class="card-header">
              <span>最新订单</span>
            </div>
          </template>
          <el-table :data="pagedOrders" border style="width: 100%">
            <el-table-column prop="orderNo" label="订单号" width="120" />
            <el-table-column prop="customer" label="客户" min-width="140" />
            <el-table-column prop="amount" label="金额" width="120">
              <template #default="{ row }">
                ¥ {{ row.amount.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="status" label="状态" width="120">
              <template #default="{ row }">
                <el-tag :type="statusTagType(row.status)">{{ row.status }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="date" label="日期" width="160" />
          </el-table>
          <div class="table-pagination">
            <el-pagination background layout="prev, pager, next" :total="orders.length" :page-size="pageSize"
              :current-page="currentPage" @current-change="handlePageChange" />
          </div>
        </el-card>
      </div>
    </main>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { Monitor, UserFilled, ShoppingCart, Setting, Fold, Expand, ArrowDown, Coin, Tickets, User, Histogram } from '@element-plus/icons-vue'
import type * as EChartsType from 'echarts'

const isCollapsed = ref(false)
const activeMenu = ref('dashboard')
const asideWidth = computed(() => (isCollapsed.value ? 64 : 200))

function toggleAside() {
  isCollapsed.value = !isCollapsed.value
}

function handleMenuSelect(index: string) {
  activeMenu.value = index
}

function handleCommand(cmd: string) {
  if (cmd === 'logout') {
    alert('已退出登录')
  } else if (cmd === 'profile') {
    alert('进入个人中心')
  }
}

// mock 统计数据
const stats = ref([
  { title: '用户总数', value: 12890, icon: User, bg: '#e0f2fe' },
  { title: '当日访问量', value: 2345, icon: Histogram, bg: '#eef2ff' },
  { title: '订单数', value: 876, icon: Tickets, bg: '#fef3c7' },
  { title: '营收（¥）', value: 985432, icon: Coin, bg: '#dcfce7' },
])

// mock 图表数据
const days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
const visitData = [120, 200, 150, 260, 300, 220, 280]
const paidRatio = [
  { name: '付费用户', value: 3200 },
  { name: '非付费用户', value: 9680 },
]

// mock 订单列表
type Order = { orderNo: string; customer: string; amount: number; status: '已支付' | '未支付' | '退款'; date: string }
const orders = ref<Order[]>(Array.from({ length: 32 }).map((_, i) => {
  const statuses: Order['status'][] = ['已支付', '未支付', '退款']
  const status = statuses[i % statuses.length]
  return {
    orderNo: `NO${(20231000 + i + 1).toString()}`,
    customer: ['张三', '李四', '王五', '赵六', '刘七'][i % 5],
    amount: Math.round(100 + Math.random() * 9000),
    status,
    date: `2025-11-${String((i % 27) + 1).padStart(2, '0')}`
  }
}))
const pageSize = 8
const currentPage = ref(1)
const pagedOrders = computed(() => {
  const start = (currentPage.value - 1) * pageSize
  return orders.value.slice(start, start + pageSize)
})
function handlePageChange(page: number) {
  currentPage.value = page
}
function statusTagType(status: Order['status']) {
  return status === '已支付' ? 'success' : status === '未支付' ? 'warning' : 'info'
}

// ECharts 动态引入（CDN），保证无需安装依赖即可使用
declare global {
  interface Window {
    echarts?: EChartsType
  }
}

function loadECharts(): Promise<EChartsType> {
  return new Promise((resolve, reject) => {
    if (window.echarts) {
      return resolve(window.echarts as unknown as EChartsType)
    }
    const script = document.createElement('script')
    script.src = 'https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js'
    script.async = true
    script.onload = () => {
      if (window.echarts) resolve(window.echarts as unknown as EChartsType)
      else reject(new Error('ECharts 加载失败'))
    }
    script.onerror = () => reject(new Error('无法加载 ECharts CDN'))
    document.head.appendChild(script)
  })
}

const lineChartRef = ref<HTMLDivElement | null>(null)
const pieChartRef = ref<HTMLDivElement | null>(null)
let lineChart: any = null
let pieChart: any = null

function initCharts(echarts: EChartsType) {
  if (lineChartRef.value) {
    lineChart = (echarts as any).init(lineChartRef.value)
    lineChart.setOption({
      grid: { left: 40, right: 20, top: 30, bottom: 30 },
      tooltip: { trigger: 'axis' },
      xAxis: { type: 'category', data: days, boundaryGap: false, axisLine: { lineStyle: { color: '#cbd5e1' } }, axisLabel: { color: '#64748b' } },
      yAxis: { type: 'value', axisLine: { show: false }, splitLine: { lineStyle: { color: '#e2e8f0' } }, axisLabel: { color: '#64748b' } },
      series: [{
        data: visitData,
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 6,
        lineStyle: { color: '#3b82f6', width: 3 },
        itemStyle: { color: '#3b82f6' },
        areaStyle: { color: 'rgba(59,130,246,0.15)' }
      }]
    })
  }
  if (pieChartRef.value) {
    pieChart = (echarts as any).init(pieChartRef.value)
    pieChart.setOption({
      tooltip: { trigger: 'item' },
      legend: { bottom: 0, textStyle: { color: '#64748b' } },
      series: [{
        name: '用户占比',
        type: 'pie',
        radius: ['50%', '70%'],
        avoidLabelOverlap: false,
        label: { show: false, position: 'center' },
        emphasis: { label: { show: true, fontSize: 16, fontWeight: 'bold', color: '#0f172a' } },
        labelLine: { show: false },
        data: [
          { value: paidRatio[0].value, name: paidRatio[0].name, itemStyle: { color: '#22c55e' } },
          { value: paidRatio[1].value, name: paidRatio[1].name, itemStyle: { color: '#94a3b8' } }
        ]
      }]
    })
  }
}

function resizeCharts() {
  if (lineChart) lineChart.resize()
  if (pieChart) pieChart.resize()
}

onMounted(async () => {
  const echarts = await loadECharts()
  initCharts(echarts)
  window.addEventListener('resize', resizeCharts)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeCharts)
  if (lineChart) lineChart.dispose()
  if (pieChart) pieChart.dispose()
})
</script>

<style scoped>
:root {
  --brand-blue: #3b82f6;
  --brand-gray: #f1f5f9;
  --brand-white: #ffffff;
  --text-main: #0f172a;
  --text-sub: #64748b;
}

.dashboard-page {
  font-family: Inter, "Noto Sans", system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  color: var(--text-main);
  background: #f8fafc;
  min-height: 100vh;
}

/* 顶部导航栏 */
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--brand-white);
  border-bottom: 1px solid #e2e8f0;
  padding: 0 16px;
  z-index: 1000;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--brand-blue);
  color: #fff;
  display: grid;
  place-items: center;
  font-weight: 700;
}

.system-name {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-main);
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.avatar-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}

.collapse-btn {
  margin-right: 8px;
}

/* 左侧菜单栏 */
.sidebar {
  position: fixed;
  top: 64px;
  bottom: 0;
  left: 0;
  background: var(--brand-white);
  border-right: 1px solid #e2e8f0;
  transition: width 0.2s ease;
}

.menu {
  height: 100%;
  border-right: none;
}

/* 主体内容区 */
.main {
  margin-top: 64px;
  padding: 16px;
  transition: margin-left 0.2s ease;
}

.content {
  max-width: 1400px;
  margin: 0 auto;
}

/* 统计卡片 */
.stats-row {
  margin-bottom: 16px;
}

.stat-card {
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
}

.stat-card-inner {
  display: flex;
  align-items: center;
  gap: 12px;
}

.stat-icon {
  width: 42px;
  height: 42px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  color: #1f2937;
}

.stat-meta {
  display: flex;
  flex-direction: column;
}

.stat-title {
  font-size: 14px;
  color: var(--text-sub);
}

.stat-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--text-main);
}

/* 图表区 */
.charts-row {
  margin-bottom: 16px;
}

.chart-card {
  border-radius: 12px;
  background: var(--brand-white);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--text-main);
  font-weight: 600;
}

.echart {
  width: 100%;
  min-height: 300px;
}

/* 表格区 */
.table-card {
  border-radius: 12px;
  background: var(--brand-white);
}

.table-pagination {
  display: flex;
  justify-content: flex-end;
  padding: 12px 8px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .system-name {
    display: none;
  }

  .content {
    padding: 0 4px;
  }

  .echart {
    min-height: 240px;
  }
}
</style>
